Line # Revision Author
1 198 ahitrov package webshop::Order;
2
3 use base "Contenido::Document";
4 270 ahitrov use Contenido::Globals;
5
6 198 ahitrov sub extra_properties
7 {
8 return (
9 504 ahitrov { 'attr' => 'name', 'type' => 'string', postedit => 1, faciledit => 1 },
10 198 ahitrov { 'attr' => 'status', 'type' => 'status', 'rusname' => 'Статус заказа', facilshow => 1, postshow => 1,
11 'cases' => [
12 [0, 'открыт'],
13 [1, 'обрабатывается'],
14 [2, 'комплектуется'],
15 [3, 'в доставке'],
16 [4, 'доставлен'],
17 [5, 'отклонен'],
18 545 ahitrov [6, 'ожидание оплаты'],
19 [7, 'товар в резерве'],
20 [8, 'не дозвонились'],
21 663 ahitrov [-1, 'удален'],
22 198 ahitrov ],
23 },
24 { 'attr' => 'delivery', 'type' => 'lookup', 'rusname' => 'Тип доставки', facilshow => 1, postshow => 1,
25 719 ahitrov 'allow_null' => 1,
26 198 ahitrov 'lookup_opts' => {
27 'class' => 'webshop::Delivery',
28 },
29 },
30 413 ahitrov { 'attr' => 'pay_by', 'type' => 'lookup', 'rusname' => 'Тип оплаты', facilshow => 1, postshow => 1,
31 719 ahitrov 'allow_null' => 1,
32 413 ahitrov 'lookup_opts' => {
33 'class' => 'webshop::Payment',
34 },
35 },
36 434 ahitrov { 'attr' => 'pay_alias', 'type' => 'string', 'rusname' => 'Название метода оплаты', shortname => 'Оплата',
37 postshow => 1, facilshow => 1 },
38 553 ahitrov { 'attr' => 'pay_amount', 'type' => 'string', 'rusname' => 'Оплаченная сумма',
39 postshow => 1, facilshow => 1 },
40 198 ahitrov { 'attr' => 'btime', 'type' => 'datetime', 'rusname' => 'Заказ отдан на комплектацию',
41 postshow => 1, facilshow => 1 },
42 { 'attr' => 'ftime', 'type' => 'datetime', 'rusname' => 'Заказ передан в доставку',
43 manager_hidden => 1, postshow => 1, faciledit => 1 },
44 { 'attr' => 'etime', 'type' => 'datetime', 'rusname' => 'Заказ доставлен',
45 manager_hidden => 1, postedit => 1, facilshow => 1 },
46 { 'attr' => 'num', 'type' => 'integer', 'rusname' => 'Количество позиций',
47 297 ahitrov manager_hidden => 1, manshow => 1, postshow => 1, facilshow => 1 },
48 422 ahitrov { 'attr' => 'sum', 'type' => 'string', 'rusname' => 'Сумма (gross)', shortname => 'Сумма',
49 297 ahitrov manager_hidden => 1, column => 5, postshow => 1, facilshow => 1 },
50 270 ahitrov { 'attr' => 'sum_discount', 'type' => 'string', 'rusname' => 'Сумма скидки', shortname => 'Скидка',
51 297 ahitrov manager_hidden => 1, column => 6, postshow => 1, facilshow => 1 },
52 198 ahitrov { 'attr' => 'sum_delivery', 'type' => 'string', 'rusname' => 'Стоимость доставки', shortname => 'Доставка',
53 297 ahitrov manager_hidden => 1, column => 7, postshow => 1, facilshow => 1 },
54 270 ahitrov { 'attr' => 'sum_total', 'type' => 'string', 'rusname' => 'Сумма общая', shortname => 'Total',
55 297 ahitrov manager_hidden => 1, column => 8, virtual => 1, postshow => 1, facilshow => 1 },
56 799 ahitrov { 'attr' => 'tracking', 'type' => 'string', 'rusname' => 'Трек-номер заказа', shortname => 'Трекинг',
57 800 ahitrov postedit => 1, faciledit => 1 },
58 198 ahitrov { 'attr' => 'contact', 'type' => 'string', 'rusname' => 'Контактное лицо', facilshow => 1 },
59 { 'attr' => 'email', 'type' => 'string', 'rusname' => 'E-mail для связи', shortname => 'E-mail',
60 259 ahitrov column => 3, postshow => 1, facilshow => 1, mandatory => 1, },
61 198 ahitrov { 'attr' => 'phone', 'type' => 'string', 'rusname' => 'Телефон для связи', shortname => 'Тел.',
62 259 ahitrov column => 4, postshow => 1, facilshow => 1,
63 mandatory => 1, rel => 'Не указан телефон' },
64 803 ahitrov { 'attr' => 'pvz_code', 'type' => 'string', 'rusname' => 'Код подразделения', postedit => 1, facilshow => 1 },
65 { 'attr' => 'address', 'type' => 'text', 'rusname' => 'Адрес доставки', rows => 5, postedit => 1, facilshow => 1,
66 298 ahitrov mandatory => 1, rel => 'Не заполнен адрес доставки' },
67 259 ahitrov { 'attr' => 'zipcode', 'type' => 'string', 'rusname' => 'Почтовый индекс', postshow => 1,
68 mandatory => 1, rel => 'Не указан почтовый индекс' },
69 { 'attr' => 'area', 'type' => 'lookup', 'rusname' => 'Регион',
70 lookup_opts => { class => 'webshop::Area', order_by => 'name' },
71 allow_null => 1, mandatory => 1, rel => 'Не выбран регион'
72 },
73 { 'attr' => 'town_id', 'type' => 'lookup', 'rusname' => 'Город',
74 lookup_opts => { class => 'webshop::Town', order_by => 'name' },
75 allow_null => 1, mandatory => 1, rel => 'Не выбран город'
76 },
77 { 'attr' => 'town', 'type' => 'string', 'rusname' => 'Город', postshow => 1, facilshow => 1,
78 mandatory => 1, rel => 'Не указан город' },
79 544 ahitrov { 'attr' => 'carrier', 'type' => 'string', 'rusname' => 'Транспортная компания', postshow => 1 },
80 297 ahitrov { 'attr' => 'metro', 'type' => 'string', 'rusname' => 'Ближайшее метро', manager_hidden => 1, postshow => 1 },
81 663 ahitrov { 'attr' => 'timeline', 'type' => 'string', 'rusname' => 'Предпочтительная дата и время', postshow => 1, },
82 304 ahitrov { 'attr' => 'description', 'type' => 'text', 'rusname' => 'Описание для курьера', rows => 5, postshow => 1, faciledit => 1 },
83 504 ahitrov { 'attr' => 'manager_comment', 'type' => 'text', 'rusname' => 'Комментарий менеджера', rows => 5, postedit => 1, faciledit => 1 },
84 297 ahitrov { 'attr' => 'facility_comment', 'type' => 'text', 'rusname' => 'Описание проблем с комплектацией', rows => 5, manager_hidden => 1, faciledit => 1 },
85 { 'attr' => 'delivery_comment', 'type' => 'text', 'rusname' => 'Описание проблем с доставкой', rows => 5, manager_hidden => 1, postedit => 1 },
86 198 ahitrov )
87 }
88
89 714 ahitrov sub recount {
90 my $self = shift;
91 my $basket = $self->keeper->{webshop}->get_basket( order_id => $self->id );
92 my $store = 0;
93 if ( ref $basket && @$basket ) {
94 my $sum = 0;
95 foreach my $bi ( @$basket ) {
96 $sum += $bi->price * $bi->number;
97 }
98 if ( $sum != $self->sum ) {
99 $self->sum( $sum );
100 $store = 1;
101 }
102 my $coupons = $self->keeper->get_documents(
103 class => 'webshop::Coupon',
104 lclass => 'webshop::OrderCouponLink',
105 );
106 }
107 if ( $store ) {
108 $self->store;
109 }
110 }
111 270 ahitrov
112 sub sum_total {
113 my $self = shift;
114
115 return ($self->sum || 0) - ($self->sum_discount || 0) + ($self->sum_delivery || 0);
116 }
117
118
119 198 ahitrov sub sum_formatted {
120 my $self = shift;
121
122 426 ahitrov my $price = $self->sum;
123 198 ahitrov $price = reverse $price;
124 $price =~ s/(\d{3})/$1\ /g;
125 $price = reverse $price;
126
127 return $price;
128 }
129
130 sub total_formatted {
131 my $self = shift;
132
133 270 ahitrov my $price = $self->sum_total;
134 return $keeper->{webshop}->price_format( $price );
135 198 ahitrov }
136
137
138 sub reject {
139 my $self = shift;
140
141 297 ahitrov # my $query = $self->{keeper}->SQL->prepare("delete from basket where order_id = ? and uid = ?");
142 # $query->execute( $self->id, $self->uid );
143 565 ahitrov
144 297 ahitrov $self->status(5);
145 $self->store;
146 198 ahitrov }
147
148 788 ahitrov sub delete {
149 my $self = shift;
150 my %opts = @_;
151 if ( $opts{mandatory} ) {
152 $self->SUPER::delete;
153 }
154 $self->reject;
155 }
156 198 ahitrov
157 sub class_name
158 {
159 return 'Заказ';
160 }
161
162 sub class_description
163 {
164 return 'Заказ';
165 }
166
167 sub class_table
168 {
169 return 'webshop::SQL::Order';
170 }
171
172 356 ahitrov sub table_links
173 {
174 return [
175 { name => 'Корзина', class => 'webshop::Basket', filter => 'order_id', field => 'order_id' },
176 ];
177 }
178 198 ahitrov
179 801 ahitrov sub contenido_status_style
180 {
181 my $self = shift;
182 return unless ref $self && $self->id;
183
184 my $ptype;
185 if ( exists $request->{profile_type}{$self->id} ) {
186 $ptype = $request->{profile_type}{$self->id};
187 } else {
188 $sth = $keeper->SQL->prepare("select p.type from orders as o join profiles as p on o.uid = p.id where o.id = ?");
189 $sth->execute( $self->id );
190 ($ptype) = $sth->fetchrow;
191 $sth->finish;
192 $request->{profile_type}{$self->id} = $ptype;
193 }
194 if ( $ptype == 2 ) {
195 return 'color:green;';
196 }
197 }
198
199 572 ahitrov sub post_store
200 565 ahitrov {
201 my $self = shift;
202 356 ahitrov
203 565 ahitrov if ( grep { $_ eq 'payments' } split /\s+/, $state->plugins ) {
204 my $action;
205 my ($lastop) = $keeper->get_documents( class => 'payments::Operation', order_id => $self->id, order_by => 'id desc', limit => 1 );
206 if ( ref $lastop ) {
207 if ( $self->status == 1 || $self->status == 2 || $self->status == 6 ) {
208 if ( $lastop->name eq 'suspend' || $lastop->name eq 'cancel' || $lastop->name eq 'close' ) {
209 $action = 'resume';
210 }
211 } elsif ( $self->status == 7 ) {
212 if ( $lastop->name ne 'suspend' ) {
213 $action = 'suspend';
214 }
215 } elsif ( $self->status == 4 ) {
216 if ( $lastop->name ne 'close' ) {
217 $action = 'close';
218 }
219 } elsif ( $self->status == 5 ) {
220 if ( $lastop->name ne 'cancel' ) {
221 $action = 'cancel';
222 }
223 }
224 } else {
225 if ( $self->status == 1 || $self->status == 2 || $self->status == 6 ) {
226 $action = 'create';
227 } elsif ( $self->status == 7 ) {
228 $action = 'suspend';
229 } elsif ( $self->status == 4 ) {
230 $action = 'close';
231 } elsif ( $self->status == 5 ) {
232 $action = 'cancel';
233 }
234 }
235 714 ahitrov if ( $action && exists $keeper->{payments} ) {
236 my $op = $keeper->{payments}->add( order => $self, type => $action, ref $user ? (uuid => $user->id) : () );
237 565 ahitrov }
238 }
239 return 1;
240 }
241
242
243 198 ahitrov sub post_delete
244 {
245 my $self = shift;
246 my @items = $self->keeper->get_documents(
247 class => 'webshop::Basket',
248 order_id => $self->id,
249 );
250 foreach my $item ( @items ) {
251 $item->delete( attachments => 1 );
252 }
253 270 ahitrov my $sql = $self->keeper->SQL->prepare('DELETE FROM webshop_order_coupons where source_id = ?');
254 $sql->execute( $self->id );
255
256 198 ahitrov 1;
257 }
258
259 1;